package cn.yunhe.shiro;

import cn.yunhe.model.Role;
import cn.yunhe.model.UserNumber;
import cn.yunhe.service.ILoginService;
import cn.yunhe.service.IRoleService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.List;

/**
 * @创建人 项目二组 鲍康
 * @创建时间 2018/1/7
 * @描述
 */
//realm 查询数据库，并且得到正确数据
public class ShiroRealm extends AuthorizingRealm {

    @Resource(name="loginServiceImpl")
    private ILoginService loginService;
    @Resource
    private IRoleService roleService;

    /**
     * 1.获取认证消息，如果数据库没有数据，返回 null ，否则返回指定类型对象
     * 2.AuthenticationInfo  可以使用    实现类，封装正确的用户名密码
     * 3.token token参数就是要认证的token
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        SimpleAuthenticationInfo info = null;
        System.out.println("1");
        //1.将token转换成 UsernamePasswordToken
        UsernamePasswordToken uToken = (UsernamePasswordToken) authenticationToken;
        //2.获取前端获得的用户名，密码
        String username = uToken.getUsername();
        //3.查询数据库，是否存在指定用户名
        UserNumber userNumber = loginService.queryUserByUserid(username);
        //4.如果查到了，封装查询结果，返回调用
        if(null!=userNumber.getUsername()){
            Object principal = userNumber.getUsername();
            Object credentials = userNumber.getPassword();
            String realmNam = this.getName();
            System.out.println(this.getName()+"----------");
            //ByteSource
//            ByteSource salt = ByteSource.Util.bytes(username);
            //将密码加密
//            SimpleHash sh = new SimpleHash("MD5",credentials,salt,1024);
            info = new SimpleAuthenticationInfo(principal,credentials,realmNam);
//            info = new SimpleAuthenticationInfo(principal,null,salt,realmNam);
        }else {
            //5.如果没有查到，
                throw new AuthenticationException();
        }
        return info;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //返回值 ：AuthorizationInfo ，封装指定用户对应的所有角色，SimpleAuthenticationInfo
        //参数：principalCollection ，登录的身份，用户名。
        SimpleAuthorizationInfo info = null;
        String username = principalCollection.toString();
        //3.查询数据库，是否存在指定用户名
        UserNumber userNumber = loginService.queryUserByUserid(username);
        //4.如果查到了，封装查询结果【角色的集合】，返回调用
        if(null!=userNumber.getUsername()){
            Set<String> roles = new HashSet<String>();
            Role r = userNumber.getRole();
            Role role = roleService.queryRoleById(r);
            String powers = role.getPowers();
            String[] power = powers.split(",");
            for (String str:power) {
                roles.add(str);
            }
            System.out.println(roles);
            info = new SimpleAuthorizationInfo(roles);
        }else {
            //5.如果没有查到，抛出异常
            throw new AuthenticationException();
        }
        return info;
    }

    public ILoginService getLoginService() {
        return loginService;
    }

    public void setLoginService(ILoginService loginService) {
        this.loginService = loginService;
    }

    public IRoleService getRoleService() {
        return roleService;
    }

    public void setRoleService(IRoleService roleService) {
        this.roleService = roleService;
    }
}
